#pragma once

#include <iostream>
const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

std::string Encode(std::string &content) // content ：100 + 200  ,用自定义协议将数据封装
{
    //"长度\n" : "9\n"
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    //"9\n"100 + 200"
    package += content;
    //"9\n"100 + 200\n"
    package += protocol_sep;
    return package;//"9\n"100 + 200\n"
}
//获得有效载荷
bool Decode(std::string &package, std::string *content) // content是有效载荷 ，例如：100 + 200
{
    //例子："9\n"100 + 200\n"
    
    // 发送过来的消息必须至少含有一个完整报文
    size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos)
        return false;
        
    std::string len_str = package.substr(0, pos); //获得"9"
 
   size_t len = stoi(len_str);//获得9

//2:两个\n , 
std::size_t total_len = len_str.size() + len + 2;  
  
    // 不是完整报文
     if(package.size() < total_len) return false;

    // 是完整报文
        *content = package.substr(pos+1,len) ;
    // 移除一个完整的报文 
    package.erase(0 ,total_len) ;
    return true ;
}

class   Request
{
public:
    Request(int data1, int data2, char oper) : x(data1), y(data2), op(oper)
    {
    }
    Request()
    {
        
    }
    ~Request()
    {

    }

    bool Serialize(std::string *out) // 序列化
    {
        //"9\n"100 + 200\n"
        // 报头：长度\n

        // 构建报文的有效载荷,"x op y"
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
        return true;
    }

    bool DeSerialize(const std::string &in) // 反序列化
    {
        //"9\n"100 + 200\n"
        size_t left = in.find(blank_space_sep);
        if (left == std::string::npos)
            return false; // 没有找到
        // 找到空格
        std::string part_x = in.substr(0, left);
        size_t right = in.rfind(blank_space_sep);
        if (right == std::string::npos)
            return false; // 没有找到
        std::string part_y = in.substr(right + 1);
        // 不是一个完整的报文
        if (left + 2 != right)
            return false;
        op = in[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);

        return true;
    }
  void DebugPrint()
    {
        std::cout << "新请求构建完成:  " << x << op << y << "=?" << std::endl;
    }
public:
    // x op y
    int x;
    int y;
    char op; // + - * / %
};

class Response
{
public:
    Response(int res, int c) : result(res), code(c)
    {
    }

    Response()
    {
        // std::cout<<"  Response()"<<std::endl;
    }

    bool Serialize(std::string *out)
    {

        // "result code"
        // 构建报文的有效载荷
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *out = s;
        return true;
    }
    bool DeSerialize(std::string &in)
    {
        // "result code"
        // 构建报文的有效载荷

        size_t pos = in.find(blank_space_sep);
        if (pos == std::string::npos)
            return false; // 没有找到
        // 找到空格
        std::string part_left = in.substr(0, pos);
        std::string part_right = in.substr(pos + 1);
        result = std::stoi(part_left);
        code = std::stoi(part_right);
        return true;
    }

  void DebugPrint()
    {
        std::cout << "结果响应完成, result: " << result << ", code: "<< code << std::endl;
    }


public:
    int result;
    int code; // 0，可信，否则!0具体是几，表明对应的错误原因
};